//
//  ControlCenter.swift
//  aquariumstudio
//
//  Created by zj on 2022/10/20.
//  Copyright © 2022 LXF. All rights reserved.
//

import Foundation

fileprivate typealias log = XXLoger

public class ControlCenter: NSObject {
    public static let shared = ControlCenter.init()
    
    
    var controlProtocolList:[ControlProtocol] = []
    
    public func regist(controlProtocol:ControlProtocol){
        controlProtocolList.append(controlProtocol)
    }
    
    private override init() {
         
    }
    
    public func getControl(typeString:String) -> ControlProtocol? {
        for cp in controlProtocolList {
            if cp.canControl(typeString) {
                return cp.copyControlProtocol()
            }
        }
        log.e("未找到能控制 \(typeString) 的 ControlProtocol")
        return nil
    }
    
    public func getControl(device:DeviceProtocol) -> ControlProtocol? {
        for cp in controlProtocolList {
            if cp.canControl(device) {
                return cp.copyControlProtocol()
            }
        }
        log.e("未找到能控制 \(device.typeString ?? "") : \(device.deviceId ?? "")的 ControlProtocol")
        return nil
    }
    
    @discardableResult
    public func doAction(list:[DeviceProtocol],control:(DeviceProtocol,ControlProtocol)->(),canotControl:((DeviceProtocol)->())? = nil) -> [ControlProtocol]{
        var rs = [ControlProtocol].init()
        for dev in list {
            if let p = doAction(device: dev, control: control,canotControl: canotControl){
                rs.append(p)
            }
        }
        return rs
    }
        
    @discardableResult
    public func doAction<TControlProtocol>(
        list:[DeviceProtocol],
        as t:TControlProtocol.Type,
        control:(DeviceProtocol,TControlProtocol)->(),
        canotControl:((DeviceProtocol)->())? = nil
    ) -> [ControlProtocol?] where TControlProtocol:ControlProtocol{
        var rs = [ControlProtocol?].init()
        for dev in list {
            if let p = doAction(device: dev,as: t, control: control,canotControl: canotControl){
                rs.append(p)
            }else{
                rs.append(nil)
            }
        }
        return rs
    }
    
    @discardableResult
    public func doAction(device:DeviceProtocol,control:(DeviceProtocol,ControlProtocol)->(),canotControl:((DeviceProtocol)->())? = nil)->ControlProtocol?{
        if let p = getControl(device: device) {
            p.device = device
            control(device,p)
            return p
        }else{
            canotControl?(device)
            return nil
        }
    }
    
    @discardableResult
    public func doAction<TControlProtocol>(device:DeviceProtocol,as:TControlProtocol.Type,
                                    control:(DeviceProtocol,TControlProtocol)->(),
                                    canotControl:((DeviceProtocol)->())? = nil)->TControlProtocol?
    where TControlProtocol:ControlProtocol{
        if let p = getControl(device: device) as? TControlProtocol{
            p.device = device
            control(device,p)
            return p
        }else{
            canotControl?(device)
            return nil
        }
    }
}
